﻿using System;
using System.Xml;

namespace Graphe.Collations
{
    public class Reading : ICollationElement, IComparable<Reading>
    {
        #region Constructor

        public Reading()
        {
            Manuscripts = new ManuscriptCollection();
        }

        #endregion
        #region Public Properties

        /// <summary>
        /// The text of the reading.
        /// </summary>
        public string Text { get; set; }

        /// <summary>
        /// The type of the reading.
        /// </summary>
        public EVariantType Type { get; set; }

        /// <summary>
        /// The manuscripts that support the reading.
        /// </summary>
        public ManuscriptCollection Manuscripts { get; set; }

        #endregion
        #region ICollationElement Members

        public void Parse(XmlReader reader, CollationDebugMessages debugMessages)
        {
            if (reader.Name != "Reading")
            {
                debugMessages.Add(String.Format("Unknown xml: {0}.", reader.ReadOuterXml()));
            }
            else
            {
                if (reader.MoveToFirstAttribute())
                {
                    do
                    {
                        ReadAndAssignAttribute(reader, debugMessages);
                    } while (reader.MoveToNextAttribute());
                }

                reader.ReadToFollowing("Text");
                reader.Read();
                Text = reader.ReadContentAsString().Trim();

                reader.ReadToFollowing("Manuscripts");
                Manuscripts = new ManuscriptCollection();
                Manuscripts.Parse(reader, debugMessages);
            }
        }

        public void Render(XmlTextWriter writer)
        {
            writer.WriteStartElement("Reading");
            if (Type != EVariantType.NotSpecified)
            {
                writer.WriteAttributeString("Type", EVariantTypeConverter.ToString(Type));
            }

            {
                writer.WriteStartElement("Text");
                writer.WriteString(Text);
                writer.WriteEndElement();

                writer.WriteStartElement("Manuscripts");
                foreach (Manuscript manuscript in Manuscripts)
                {
                    manuscript.Render(writer);
                }
                writer.WriteEndElement();
            }
            writer.WriteEndElement();
        }

        #endregion
        #region IComparable<Reading> Members

        public int CompareTo(Reading other)
        {
            if (this.Text != other.Text || this.Type != other.Type)
                return -1;
            if (this.Manuscripts.CompareTo(other.Manuscripts) == -1)
                return -1;

            return 0;
        }

        #endregion

        private void ReadAndAssignAttribute(XmlReader reader, CollationDebugMessages debugMessages)
        {
            if (reader.Name == "Type")
            {
                string attributeValue = reader.ReadContentAsString();
                try
                {
                    Type = EVariantTypeConverter.ToEnum(attributeValue);
                }
                catch (ArgumentException exc)
                {
                    debugMessages.Add(String.Format("The value of '{0}' for the Type attribute for the reading being parsed is unknown. This value will be removed when the collation is saved.", attributeValue));
                }
            }
            else
            {
                debugMessages.Add(String.Format("Attribute '{0}' with value '{1}' is unknown for a reading and will not be persisted in the in-memory model. This also means it won't be saved after you change the collation.", reader.Name, reader.ReadContentAsString()));
            }
        }
    }
}
